home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #3 / Amiga Plus CD - 1997 - No. 03.iso / pd / programmierung / vbcc / flow.c < prev    next >
C/C++ Source or Header  |  1996-12-22  |  22KB  |  523 lines

  1. /*  $VER: vbcc (flow.c) V0.4     */
  2. /*  Generierung des FLussgraphs und Optimierungen des Kontrollflusses   */
  3.  
  4. #include "opt.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. int bvcmp(unsigned char *dest,unsigned char *src,size_t len)
  9. /*  vergleicht zwei Bitvektoren    */
  10. {
  11.     for(;len>0;len--)
  12.         if(*dest++!=*src++) return(0);
  13.     return(1);
  14. }
  15. void bvunite(unsigned char *dest,unsigned char *src,size_t len)
  16. /*  berechnet Vereinigung zweier Bitvektoren    */
  17. {
  18.     for(;len>0;len--)
  19.         *dest++|=*src++;
  20. }
  21. void bvintersect(unsigned char *dest,unsigned char *src,size_t len)
  22. /*  berechnet Durchschnitt zweier Bitvektoren   */
  23. {
  24.     for(;len>0;len--)
  25.         *dest++&=*src++;
  26. }
  27. void bvdiff(unsigned char *dest,unsigned char *src,size_t len)
  28. /*  berechnet 'Differenz' zweier Bitvektoren    */
  29. {
  30.     for(;len>0;len--)
  31.         *dest++&=~(*src++);
  32. }
  33.  
  34. unsigned int basic_blocks;
  35.  
  36. struct flowgraph *construct_flowgraph(void)
  37. /*  entfernt ueberfluessige Labels und erzeugt Flussgraph   */
  38. {
  39.     struct IC *p;
  40.     int firstl=lastlabel,lcnt=label-firstl,currentl,i,code,l;
  41.     int *iseq=mymalloc(lcnt*sizeof(int));
  42.     int *used=mymalloc(lcnt*sizeof(int));
  43.     struct flowgraph **lg=mymalloc(lcnt*sizeof(struct flowgraph *));
  44.     struct flowgraph *g=mymalloc(sizeof(struct flowgraph)),*fg=g;
  45.     g->start=first_ic;g->in=0;g->branchout=0;g->loopend=0;
  46.  
  47.     for(i=0;i<lcnt;i++) {iseq[i]=used[i]=0;lg[i]=0;}
  48.     currentl=0;firstl++;
  49.     /*  Diese Schleife entfernt alle Labels, die mit anderen    */
  50.     /*  uebereinstimmen, merkt sich das und kennzeichnet alle   */
  51.     /*  Labels, die benutzt werden.                             */
  52.     /*  Ausserdem wird der Flussgraph teilweise aufgebaut.      */
  53.     if(DEBUG&1024) {puts("construct_flowgraph(): loop1");/*scanf("%d",&i);*/}
  54.     i=1;g->index=i;
  55.     for(p=first_ic;p;p=p->next){
  56.         code=p->code;
  57.         if(code>=BEQ&&code<=BRA){
  58.             l=p->typf;
  59.             /*  als used markieren; falls aequivalent, das erste markieren  */
  60.             if(iseq[l-firstl]) used[iseq[l-firstl]-firstl]=1;
  61.                 else           used[l-firstl]=1;
  62.             /*  Flussgraph beenden und evtl. naechsten Knoten erzeugen  */
  63.             g->end=p;
  64.             if(p->next){
  65.                 g->normalout=mymalloc(sizeof(struct flowgraph));
  66.                 g->normalout->in=mymalloc(sizeof(struct flowlist));
  67.                 g->normalout->in->next=0;
  68.                 g->normalout->in->graph=g;
  69.                 g=g->normalout;
  70.                 g->start=p->next;
  71.                 g->branchout=0;
  72.                 g->loopend=0;
  73.                 g->index=++i;
  74.             }else g->normalout=0;
  75.  
  76.             currentl=0;continue;
  77.         }
  78.         if(code==ALLOCREG||code==FREEREG) continue;
  79.         if(code!=LABEL){currentl=0;continue;}
  80.         /*  ist ein Label   */
  81.         l=p->typf;
  82.         if(currentl){
  83.             iseq[l-firstl]=currentl;
  84.             if(used[l-firstl]) used[currentl-firstl]=1;
  85.             remove_IC(p);
  86. /*            if(DEBUG&1024) printf("label %d==%d\n",l,iseq[l-firstl]);*/
  87.         }else{
  88.             currentl=l;
  89.             if(g->start!=p){
  90.                 g->end=p->prev;
  91.                 g->normalout=mymalloc(sizeof(struct flowgraph));
  92.                 g->normalout->in=mymalloc(sizeof(struct flowlist));
  93.                 g->normalout->in->next=0;
  94.                 g->normalout->in->graph=g;
  95.                 g=g->normalout;
  96.                 g->start=p;
  97.                 g->branchout=0;
  98.                 g->loopend=0;
  99.                 g->index=++i;
  100.             }else g->branchout=0;
  101.             lg[l-firstl]=g;
  102.         }
  103.     }
  104.     g->end=last_ic;g->normalout=g->branchout=0;
  105.     if(DEBUG&1024) printf("%d basic blocks\n",i);
  106.     basic_blocks=i;
  107.  
  108. /*    if(DEBUG&1024) for(i=firstl;i<=lcnt;i++) printf("L%d used: %d\n",i,used[i-firstl]);*/
  109.     /*  Diese Schleife entfernt alle nicht benutzten Labels und biegt alle  */
  110.     /*  Branches auf aequivalente Labels um.                                */
  111.     if(DEBUG&1024) {puts("construct_flowgraph(): loop2");/*scanf("%d",&i);*/}
  112.     g=fg;
  113.     while(g){
  114.         int flag=0;struct flowlist *lp;
  115. /*        printf("g=%p\n",(void *)g);*/
  116.         g->av_in=g->av_out=g->av_gen=g->av_kill=0;
  117.         g->rd_in=g->rd_out=g->rd_gen=g->rd_kill=0;
  118.         g->ae_in=g->ae_out=g->ae_gen=g->ae_kill=0;
  119.         g->cp_in=g->cp_out=g->cp_gen=g->cp_kill=0;
  120.         p=g->start;
  121.         while(p&&!flag){
  122. /*            pric2(stdout,p);*/
  123.             code=p->code;
  124.             if(code>=BEQ&&code<=BRA){
  125.                 l=p->typf;
  126.                 if(iseq[l-firstl]) p->typf=l=iseq[l-firstl];
  127.                 /*  in Flussgraph eintragen */
  128.                 g->branchout=lg[l-firstl];
  129.                 if(!lg[l-firstl]) ierror(0);
  130.                 lp=lg[l-firstl]->in;
  131.                 /*  das hier sollte man noch schoener machen    */
  132.                 if(!lp){
  133.                     lg[l-firstl]->in=mymalloc(sizeof(struct flowlist));
  134.                     lg[l-firstl]->in->next=0;
  135.                     lg[l-firstl]->in->graph=g;
  136.                 }else{
  137.                     while(lp&&lp->next) lp=lp->next;
  138.                     lp->next=mymalloc(sizeof(struct flowlist));
  139.                     lp->next->next=0;
  140.                     lp->next->graph=g;
  141.                 }
  142.             }
  143. /*            if(code==LABEL&&!used[p->typf-firstl]) remove_IC(p);*/
  144.             if(p==g->end) flag=1;
  145.             p=p->next;
  146.         }
  147.         g=g->normalout;
  148.     }
  149.     /*  Unbenutzte Labels entfernen und Bloecke verbinden   */
  150.     if(DEBUG&1024) {puts("construct_flowgraph(): loop3");/*scanf("%d",&i);*/}
  151.     for(g=fg;g;g=g->normalout){
  152.         if(g->end&&(g->end->code<BEQ||g->end->code>BRA)){
  153.             struct flowgraph *next=g->normalout;struct flowlist *lp;
  154.             if(next&&next->start&&next->start->code==LABEL&&!used[next->start->typf-firstl]){
  155.                 if(next->end!=next->start) g->end=next->end;
  156.                 g->normalout=next->normalout;
  157.                 g->branchout=next->branchout;
  158.                 free(next->in); /*  darf eigentlich nur einen Vorgaenger haben  */
  159.                 /*  in im Nachfolgeknoten auf den ersten der beiden setzen  */
  160.                 if(next->normalout&&next->normalout->in) next->normalout->in->graph=g;
  161.                 /*  in im Ziel von next->branchout auf den ersten setzen    */
  162.                 if(next->branchout){
  163.                     lp=next->branchout->in;
  164.                     while(1){
  165.                         if(lp->graph==next){ lp->graph=g;break;}
  166.                         lp=lp->next;if(!lp) ierror(0);
  167.                     }
  168.                 }
  169.                 if(DEBUG&1024){ printf("unused label deleted:\n");pric2(stdout,next->start);}
  170.                 remove_IC(next->start);
  171.                 free(next);
  172.             }
  173.         }
  174.         /*  unbenutzte Labels entfernen */
  175.         if(g->start&&g->start->code==LABEL&&!used[g->start->typf-firstl])
  176.             remove_IC_fg(g,g->start);
  177.     }
  178.     free(iseq);
  179.     free(used);
  180.     return(fg);
  181. }
  182.  
  183. void print_flowgraph(struct flowgraph *g)
  184. /*  Gibt Flussgraph auf Bildschirm aus  */
  185. {
  186.     static int dontprint=0;
  187.     int flag,i;struct flowlist *lp;struct IC *ip;
  188.     if(dontprint) return;
  189.     puts("print_flowgraph()");scanf("%d",&i);
  190.     if(i<0){dontprint=1;return;}
  191.     if(!i) return;
  192.     while(g){
  193.         printf("\nBasic Block nr. %d\n",g->index);
  194.         printf("\tin from ");
  195.         lp=g->in;
  196.         while(lp){if(lp->graph) printf("%d ",lp->graph->index);lp=lp->next;}
  197.         printf("\n\tout to %d %d\n",g->normalout?g->normalout->index:0,g->branchout?g->branchout->index:0);
  198.         if(g->loopend) printf("head of a loop ending at block %d\n",g->loopend->index);
  199.         if(i&2){
  200.             printf("av_gen:\n"); print_av(g->av_gen);
  201.             printf("av_kill:\n"); print_av(g->av_kill);
  202.             printf("av_in:\n"); print_av(g->av_in);
  203.             printf("av_out:\n"); print_av(g->av_out);
  204.         }
  205.         if(i&4){
  206.             printf("rd_gen:\n"); print_rd(g->rd_gen);
  207.             printf("rd_kill:\n"); print_rd(g->rd_kill);
  208.             printf("rd_in:\n"); print_rd(g->rd_in);
  209.             printf("rd_out:\n"); print_rd(g->rd_out);
  210.         }
  211.         if(i&8){
  212.             printf("ae_gen:\n"); print_ae(g->ae_gen);
  213.             printf("ae_kill:\n"); print_ae(g->ae_kill);
  214.             printf("ae_in:\n"); print_ae(g->ae_in);
  215.             printf("ae_out:\n"); print_ae(g->ae_out);
  216.         }
  217.         if(i&16){
  218.             printf("cp_gen:\n"); print_cp(g->cp_gen);
  219.             printf("cp_kill:\n"); print_cp(g->cp_kill);
  220.             printf("cp_in:\n"); print_cp(g->cp_in);
  221.             printf("cp_out:\n"); print_cp(g->cp_out);
  222.         }
  223.         if(i&32){
  224.             int r;
  225.             for(r=1;r<=MAXR;r++)
  226.                 if(g->regv[r]) printf("(%s),%ld assigned to %s\n",g->regv[r]->identifier,(long)zl2l(g->regv[r]->offset),regnames[r]);
  227.         }
  228.         flag=0;ip=g->start;
  229.         while(ip&&!flag){
  230.             pric2(stdout,ip);
  231.             if(i&64){
  232.                 int r;
  233.                 printf("changes: ");
  234.                 for(r=0;r<ip->change_cnt;r++)
  235.                     printf("(%s,%ld,%d)",ip->change_list[r].v->identifier,(long)zl2l(ip->change_list[r].v->offset),ip->change_list[r].flags);
  236.                 printf("\nuses: ");
  237.                 for(r=0;r<ip->use_cnt;r++)
  238.                     printf("(%s,%ld,%d)",ip->use_list[r].v->identifier,(long)zl2l(ip->use_list[r].v->offset),ip->use_list[r].flags);
  239.                 printf("\n");
  240.             }
  241.             if(ip==g->end) flag=1;
  242.             ip=ip->next;
  243.         }
  244.         g=g->normalout;
  245.     }
  246. }
  247. void free_flowgraph(struct flowgraph *g)
  248. /*  Gibt Flussgraph frei    */
  249. {
  250.     struct flowgraph *pm;struct flowlist *lp,*lpm;
  251.     if(DEBUG&1024) puts("free_flowgraph()");
  252.     while(g){
  253.         lp=g->in;
  254.         while(lp){
  255.             lpm=lp->next;
  256.             free(lp);
  257.             lp=lpm;
  258.         }
  259.         free(g->av_in);
  260.         free(g->av_out);
  261.         free(g->av_gen);
  262.         free(g->av_kill);
  263.         free(g->rd_in);
  264.         free(g->rd_out);
  265.         free(g->rd_gen);
  266.         free(g->rd_kill);
  267.         free(g->ae_in);
  268.         free(g->ae_out);
  269.         free(g->ae_gen);
  270.         free(g->ae_kill);
  271.         free(g->cp_in);
  272.         free(g->cp_out);
  273.         free(g->cp_gen);
  274.         free(g->cp_kill);
  275.  
  276.         pm=g->normalout;
  277.         free(g);
  278.         g=pm;
  279.     }
  280. }
  281. struct flowgraph *jump_optimization(void)
  282. /*  entfernt ueberfluessige Spruenge etc.                           */
  283. {
  284.     struct flowgraph *fg,*g;struct IC *p;int changed,i;
  285.     struct flowlist *lp;
  286.     do{
  287.         changed=0;
  288.         fg=construct_flowgraph();
  289.         if(DEBUG&1024) {printf("jump_optimization() pass\n");print_flowgraph(fg);}
  290.         g=fg;
  291.         while(g){
  292.             /*  tote Bloecke entfernen                  */
  293.             if(g!=fg) i=0; else i=1;    /*  erster Block nie tot    */
  294.             lp=g->in;
  295.             while(!i&&lp){
  296.                 struct flowgraph *t=lp->graph;
  297.                 if(t){
  298.                     if((t!=g&&t->branchout==g)||!t->end||(t!=g&&t->end->code!=BRA)) i=1;
  299.                 }
  300.                 lp=lp->next;
  301.             }
  302.             if(!i){
  303.                 struct IC *m;
  304.                 if(DEBUG&1024) printf("deleting dead block %d\n",g->index);
  305.                 p=g->start;
  306.                 while(p&&!i){
  307.                     if(p==g->end) i=1;
  308.                     if(DEBUG&1024) pric2(stdout,p);
  309.                     m=p->next;
  310.                     remove_IC_fg(g,p);changed=gchanged=1;
  311.                     p=m;
  312.                 }
  313.                 if(g->branchout){
  314.                 /*  Eintrag in Ziel loeschen (nur einmal, falls auch normalout)    */
  315.                     lp=g->branchout->in;
  316.                     while(lp){
  317.                         if(lp->graph==g){ lp->graph=0;break;}
  318.                         lp=lp->next;
  319.                     }
  320.                     g->branchout=0;
  321.                 }
  322.                 g=g->normalout;continue;
  323.             }
  324.             /*  Spruenge zum folgenden Code entfernen   */
  325.             if(g->normalout&&g->normalout==g->branchout){
  326.                 p=g->end;
  327.                 if(!p||p->code<BEQ||p->code>BRA) ierror(0);
  328.                 if(DEBUG&1024){printf("branch to following label deleted:\n");pric2(stdout,p);}
  329.                 remove_IC_fg(g,p);g->branchout=0;changed=gchanged=1;
  330.                 p=g->end;
  331.                 /*  vorangehenden Vergleich auch entfernen  */
  332.                 if(p&&(p->code==COMPARE||p->code==TEST)){
  333.                     if(DEBUG&1024){printf("preceding comparison also deleted:\n");pric2(stdout,p);}
  334.                     remove_IC_fg(g,p);
  335.                 }
  336.             }
  337.             /*  Spruenge zu Spruengen umsetzen; einige Zeiger im Flussgraph */
  338.             /*  werden nicht korrekt aktualisiert, aber das sollte egal sein*/
  339.             p=g->start;
  340.             for(i=0;i<2;i++){
  341.                 if(i){if(p&&p->code==LABEL) p=p->next; else break;}
  342.                 if(p&&p->code>=BEQ&&p->code<=BRA){
  343.                     lp=g->in;
  344.                     while(lp){
  345.                         if(lp->graph&&lp->graph->branchout==g&&(/*lp->graph->end->code==p->code||*/p->code==BRA)&&lp->graph->end->typf!=p->typf){
  346.                             if(DEBUG&1024){printf("branch bypassed to L%d:\n",p->typf);pric2(stdout,lp->graph->end);}
  347.                             if(lp->graph->end->code<BEQ||lp->graph->end->code>BRA) ierror(0);
  348.                             lp->graph->branchout=g->branchout;
  349.                             lp->graph->end->typf=p->typf;changed=gchanged=1;
  350.                         }
  351.                         lp=lp->next;
  352.                     }
  353.                 }
  354.             }
  355.             /*  bcc l1;bra l2;l1 aendern    */
  356.             p=g->end;
  357.             if(p&&p->code>=BEQ&&p->code<BRA&&g->normalout){
  358.                 if(g->normalout->start&&g->normalout->start->code==BRA){
  359.                     if(g->normalout->normalout==g->branchout){
  360.                         g->branchout=g->normalout->branchout;
  361.                         i=p->typf;
  362.                         p->typf=g->normalout->start->typf;
  363.                         if(DEBUG&1024) printf("changing bcc l%d;bra l%d;l%d to b!cc l%d\n",i,p->typf,i,p->typf);
  364.                         switch(p->code){
  365.                         case BEQ: p->code=BNE;break;
  366.                         case BNE: p->code=BEQ;break;
  367.                         case BLT: p->code=BGE;break;
  368.                         case BGE: p->code=BLT;break;
  369.                         case BGT: p->code=BLE;break;
  370.                         case BLE: p->code=BGT;break;
  371.                         }
  372.                         g->normalout->branchout=g->normalout->normalout;
  373.                         g->normalout->start->typf=i;
  374.                         changed=gchanged=1;
  375.                     }
  376.                 }
  377.             }
  378.             /*  Haben alle Vorgaenger eines Blocks die selbe Anweisung am   */
  379.             /*  Blockende und keinen weiteren Nachfolger, dann kann die     */
  380.             /*  Anweisung in den Nachfogerblock geschoben werden            */
  381.             i=0;p=0;
  382.             for(lp=g->in;lp;lp=lp->next){
  383.                 if(lp->graph){
  384.                     struct IC *np;
  385.                     struct flowgraph *ng=lp->graph;
  386.                     struct flowlist *l2;
  387.                     /*  doppelte Bloecke loeschen und ueberspringen */
  388.                     for(l2=g->in;l2;l2=l2->next)
  389.                         if(l2!=lp&&l2->graph==ng) break;
  390.                     if(l2){ lp->graph=0;continue;}
  391.                     np=ng->end;
  392.                     if(!np){ i=-1;break;}
  393.                     if(ng->branchout&&np->code!=BRA){i=-1;break;}
  394.                     if(np->code==BRA) np=np->prev;
  395.                     if(!np){ i=-1;break;}
  396.                     if(!p){
  397.                         i=1;
  398.                         p=np;
  399.                     }else{
  400.                         if(p->code==np->code&&p->typf==np->typf&&
  401.                            p->code!=CALL&&p->code!=GETRETURN&&p->code!=PUSH&&(p->code<TEST||p->code>COMPARE)&&
  402.                            !compare_objs(&p->q1,&np->q1,p->typf)&&
  403.                            !compare_objs(&p->q2,&np->q2,p->typf)&&
  404.                            !compare_objs(&p->z,&np->z,p->typf)){
  405.                             i++;
  406.                         }else{
  407.                             i=-1;
  408.                             break;
  409.                         }
  410.                     }
  411.                 }
  412.             }
  413.             if(i>1&&g->start){
  414.                 struct IC *new=mymalloc(ICS);
  415.                 if(DEBUG&1024){ printf("moving instruction from preceding blocks to successor:\n");pric2(stdout,p);}
  416.                 changed=gchanged=1;
  417.                 memcpy(new,p,ICS);
  418.                 new->use_cnt=new->change_cnt=0;
  419.                 new->use_list=new->change_list=0;
  420.                 if(g->start->code==LABEL){
  421.                     insert_IC_fg(g,g->start,new);
  422.                 }else{
  423.                     insert_IC_fg(g,g->start->prev,new);
  424.                 }
  425.                 for(lp=g->in;lp;lp=lp->next){
  426.                     struct flowgraph *ng=lp->graph;
  427.                     if(ng){
  428.                         if(!ng->end) ierror(0);
  429.                         if(ng->end->code==BRA){
  430.                             remove_IC_fg(ng,ng->end->prev);
  431.                         }else{
  432.                             remove_IC_fg(ng,ng->end);
  433.                         }
  434.                     }
  435.                 }
  436.             }
  437.             /*  Haben alle Nachfolger eines Blocks die selbe Anweisung am   */
  438.             /*  Blockbeginn und keinen weiteren Vorgaenger, dann kann die   */
  439.             /*  Anweisung in den Vorgaengerblock geschoben werden           */
  440.             if(g->branchout&&g->normalout&&g->branchout!=g->normalout&&g->end&&g->end->code!=BRA){
  441.                 struct flowgraph *a=g->normalout,*b=g->branchout;
  442.                 struct IC *as=a->start,*bs=b->start,*tp;
  443.                 int destroys;
  444.                 if(as&&as->code==LABEL&&as!=a->end) as=as->next;
  445.                 if(bs&&bs->code==LABEL&&bs!=b->end) bs=bs->next;
  446.  
  447.                 if(as&&bs&&as->code==bs->code&&as->code!=PUSH&&(as->code<TEST||as->code>COMPARE)&&as->typf==bs->typf&&
  448.                    !compare_objs(&as->q1,&bs->q1,as->typf)&&
  449.                    !compare_objs(&as->q2,&bs->q2,as->typf)&&
  450.                    !compare_objs(&as->z,&bs->z,as->typf)){
  451.                     i=0;
  452.                     for(lp=a->in;lp;lp=lp->next)
  453.                         if(lp->graph&&lp->graph!=g&&(!lp->graph->end||lp->graph->end->code!=BRA)) i=1;
  454.                     for(lp=b->in;lp;lp=lp->next)
  455.                         if(lp->graph&&lp->graph!=g&&(!lp->graph->end||lp->graph->end->code!=BRA)) i=1;
  456.                     if(!i){
  457.                         if(!(tp=g->end->prev)) ierror(0);
  458.                         if(tp->code!=TEST&&tp->code!=COMPARE)
  459.                             ierror(0);
  460.                         /*  schauen, ob die Anweisung eine evtl. TEST   */
  461.                         /*  oder COMPARE-Anweisung beeinflusst          */
  462.                         destroys=0;
  463.                         if(as->z.flags&DREFOBJ) destroys|=1;
  464.                         if(as->code==CALL) destroys|=2;
  465.                         if(tp->q1.flags&VAR){
  466.                             if(destroys&3){
  467.                                 if((tp->q1.v->flags&USEDASADR)||
  468.                                    (tp->q1.flags&DREFOBJ)||
  469.                                    (tp->q1.v->storage_class==EXTERN)||
  470.                                    (tp->q1.v->nesting==0))
  471.                                     i=1;
  472.                                 if((destroys&2)&&tp->q1.v->storage_class==STATIC)
  473.                                     i=1;
  474.                             }
  475.                             if((as->z.flags&VAR)&&as->z.v==tp->q1.v)
  476.                                     i=1;
  477.                         }
  478.                         if(tp->q2.flags&VAR){
  479.                             if(destroys&3){
  480.                                 if((tp->q2.v->flags&USEDASADR)||
  481.                                    (tp->q2.flags&DREFOBJ)||
  482.                                    (tp->q2.v->storage_class==EXTERN)||
  483.                                    (tp->q2.v->nesting==0))
  484.                                     i=1;
  485.                                 if((destroys&2)&&tp->q2.v->storage_class==STATIC)
  486.                                     i=1;
  487.                             }
  488.                             if((as->z.flags&VAR)&&as->z.v==tp->q2.v)
  489.                                 i=1;
  490.                         }
  491.                         if(!i){
  492.                             if(DEBUG&1024){ printf("moving instruction from following blocks to predecessor:\n");pric2(stdout,as);}
  493.                             p=mymalloc(ICS);
  494.                             memcpy(p,as,ICS);
  495.                             remove_IC_fg(a,as);
  496.                             remove_IC_fg(b,bs);
  497.                             p->use_cnt=p->change_cnt=0;
  498.                             p->use_list=p->change_list=0;
  499.                             insert_IC_fg(g,g->end->prev->prev,p);
  500.                             changed=gchanged=1;
  501.                         }
  502.                     }
  503.                 }
  504.             }
  505.             g=g->normalout;
  506.         }
  507.         if(changed) free_flowgraph(fg);
  508.     }while(changed);
  509.     return(fg);
  510. }
  511.  
  512. void insert_IC_fg(struct flowgraph *fg,struct IC *p,struct IC *new)
  513. /*  fuegt ein IC hinter p ein unter Beibehaltung des Flussgraphen   */
  514. {
  515.     if(fg->start){
  516.         if(!p||p==fg->start->prev) fg->start=new;
  517.         if(p==fg->end) fg->end=new;
  518.     }else{
  519.         fg->start=fg->end=new;
  520.     }
  521.     insert_IC(p,new);
  522. }
  523.